#include "clientlogin.h"
#include "ui_clientlogin.h"

#include <QDebug>
#include <unistd.h>
#include <sys/socket.h>

void ClientLogin::initClient()
{
    m_clientThread = new QThread(this);
    m_client = new Client;
    m_client->moveToThread(m_clientThread);
    m_clientThread->start();
    // 发送开始连接信号
    connect(this, &ClientLogin::startConnect, m_client, &Client::connecting);
    // 处理connect状态，并获取套结字描述符
    connect(m_client, &Client::connectStatus, this, &ClientLogin::dealConnectStatus);
}

void ClientLogin::initUi()
{
    // 应用层头部（0开始代表用户名，2代表密码，1开始代表聊天消息, 3/4代表服务器验证通过/失败）

    // 点击发送按钮
    connect(ui->sendMsgBtn, &QPushButton::clicked, this, [=](){
        QString myMsg = ui->editBox->text();
        ui->editBox->clear();
        ui->chatBox->append("我：" + myMsg + '\n');
        // 应用层头部封装
        emit sendMsg('1' + myMsg);
    });
    // 读线程，接受服务器消息
    connect(m_clientRead, &ClientRead::showReceivedMsg, this, [=](QString msg){
        // 应用层头部解析
        if (msg.startsWith('3'))
        {
            qDebug() << "client get auth successed.";
            m_loginDialog->reject();
        }
        else if (msg.startsWith('4'))
        {
            m_loginDialog->tipWrong();
        }
        else if (msg.startsWith('1'))
        {
            msg = msg.right(msg.size() - 1);
            ui->chatBox->append("服务器：" + msg + '\n');
        }

    });
}

ClientLogin::ClientLogin(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ClientLogin)
{
    ui->setupUi(this);
    m_loginDialog = new LoginDialog;


    initClient();

    m_clientReadThread = new QThread(this);
    m_clientRead = new ClientRead;
    m_clientRead->moveToThread(m_clientReadThread);
    m_clientReadThread->start();
    // 建立连接成功，开始收数据
    connect(this, &ClientLogin::startOperate, m_clientRead, &ClientRead::reading);

    m_clientWriteThread = new QThread(this);
    m_clientWrite = new ClientWrite;
    m_clientWrite->moveToThread(m_clientWriteThread);
    m_clientWriteThread->start();
    // 建立连接成功，开始收数据
    connect(this, &ClientLogin::startOperate, m_clientWrite, &ClientWrite::writing);
    // 向客户端读写线程发送停止信号（特别是读，结束循环）
    connect(this, &ClientLogin::stopThread, m_clientRead, &ClientRead::stopNow);
    connect(this, &ClientLogin::stopThread, m_clientWrite, &ClientWrite::stopNow);

    // 使用客户端写线程发送数据
    connect(this, &ClientLogin::sendMsg, m_clientWrite, &ClientWrite::sendMyMsg);

    initUi();

    emit startConnect();
    connect(m_loginDialog, &LoginDialog::sendUsername, this, [=](QString username){
        qDebug() << "clientLogin get" << username;
        emit sendMsg('0' + username);
    });
    connect(m_loginDialog, &LoginDialog::sendPassword, this, [=](QString password){
        qDebug() << "clientLogin get" << password;
        emit sendMsg('2' + password);
    });
}

ClientLogin::~ClientLogin()
{
    qDebug() << "clientlogin 开始执行析构函数";
    delete ui;

    emit stopThread();

    shutdown(m_clientFd, SHUT_RD);
    ::close(m_clientFd);

    m_clientThread->quit();
    m_clientThread->wait();
    qDebug() << "客户端线程成功关闭";
//    m_clientThread->deleteLater();

    m_clientReadThread->quit();
    m_clientReadThread->wait();
    qDebug() << "客户端读线程成功关闭";
//    m_clientReadThread->deleteLater();

    m_clientWriteThread->quit();
    m_clientWriteThread->wait();
    qDebug() << "客户端写线程成功关闭";
//    m_clientWriteThread->deleteLater();

    m_client->deleteLater();
    m_clientRead->deleteLater();
    m_clientWrite->deleteLater();
    qDebug() << "clientlogin 析构函数执行完毕";
}

void ClientLogin::dealConnectStatus(int status)
{
    if (status > 0)
    {
        qDebug() << "clientLogin: I know connect successed, clientfd is" << status;
        m_clientFd = status;
        emit startOperate(status);
    }
    else
    {
        qDebug() << "clientLogin: I know connect failed.";
    }
}


